#include <string>
#include <boost/bind.hpp>
#include <boost/format.hpp>
#include <muduo/base/Logging.h>
#include <muduo/base/ThreadLocalSingleton.h>
#include <json.hh>
#include "FlightChessBoardSession.h"
#include "FlightChessBoardErrDesc.h"
#include "FlightChessBoardSystemConfig.h"

using namespace muduo;
using namespace std;
using namespace JSON;
using namespace boost;

namespace model_flight_chess_board
{
	static void
	SendEmpty(const char *,size_t)
	{
		//一个空函数，只是为了初始化占位置
	}

	static void
	SendErrEmpty(uint32_t,const char *)
	{
		//一个空函数，只是为了初始化占位置
	}

	static void
	RecvEmpty()
	{
		//一个空函数，只是为了初始化占位置
	}

	FlightChessBoardSession::FlightChessBoardSession()
	{
		//对一些成员进行初始化
		buffer_.clear();
		buffer_.resize(2048);
		sfp_ = boost::bind(&SendEmpty,_1,_2);
		rfp_ = boost::bind(&RecvEmpty);
		sefp_ = boost::bind(&SendErrEmpty,_1,_2);
	}

	FlightChessBoardSession::~FlightChessBoardSession()
	{
		//对会话进行一些回收工作
		buffer_.clear();
	}

	void
	FlightChessBoardSession::Init(const char *buf,size_t len)
	{
		//对数据进行接收初始化
		buffer_.clear();
		buffer_.assign(buf,buf + (len - 1));
	}

	void
	FlightChessBoardSession::Recv()
	{
		//调用接收回调对数据进行接收处理
		rfp_();
	}

	void
	FlightChessBoardSession::Process()
	{
		//響應構造的消息緩衝
		static std::string res_msg;
		//進程表的緩衝結構
		static std::string f_rec_list_str;
		static uint32_t f_rec_list_count = 0;
		//接收数据
		Recv();
		//从缓冲区中取出数据进行进一步解析
		std::string s(buffer_.begin(), buffer_.end());
		//这里使用json进行解析
		Value v = parse_string(s.c_str());
		Value f_type = v["request_type"];
		if((std::string)f_type == "echo test") {
			//进行回射服务器的测试发送
			//用于客户端测试和服务端的连通性
			//{"request_type":"echo_test","msg":"<your msg>"}
			Value e_msg = v["msg"];
			//{"response_type":"echo_test","msg":"<your msg>"}
			boost::format res_fmt("{\"response_type\":\"echo test\",\"msg\":\"%s\"}");
			res_fmt % (std::string)e_msg;
			res_msg = res_fmt.str();
			//這裏還需要對響應包進行組包
			Send(res_msg.c_str(),res_msg.size() + 1);
		} else if((std::string)f_type == "get airline list") {
			//客户端航线数据列表请求模块实现
			//主要是返回一個基本的航線json結構
			//BaseConnInfoHead|{"response_type":"get airline list",
			//"airline_list":[{"airline_name":"xxxx","airline_location_points_list":
			//[{x:00,y:00},...]},{},...]}
			FlightChessBoardSystemConfig &sysconf = \
				ThreadLocalSingleton<FlightChessBoardSystemConfig>::instance();
			const std::string &res_msg_ = sysconf.GetFlightChessAirLineList();
			Send(res_msg_.c_str(),res_msg_.size() + 1);
		} else if((std::string)f_type == "get plane list") {
			//客户端飞机型号列表请求模块实现
			//BaseConnInfoHead|{"response_type":"get plane list",
			//"list":[{"plane_name":"xxx"},...]}
			FlightChessBoardSystemConfig &sysconf = \
				ThreadLocalSingleton<FlightChessBoardSystemConfig>::instance();
			const std::string &res_msg_ = sysconf.GetFlightChessPlaneNoList();
			Send(res_msg_.c_str(),res_msg_.size() + 1);
		} else if((std::string)f_type == "get flight record list") {
			//进程表请求模块实现，不過這裏就直接返回客戶端上報上來的數據
			//類似一個回射服務器的變種實現
			//不過要注意在多線程的情況下應該使用一個公共緩衝區來完成數據
			//的緩存，否則會造成返回數據不全的情況
			//後面的辦法是爲每個公共資源實現公共管理線程，然後註冊回調到
			//線程池中，當各個線程池調用的時候，可以將數據轉移到這個公共
			//管理線程中來處理
			//BaseConnInfoHead|{"response_type":"get flight record list","list_len":0
			//"list":"相關的數據結構"}
			if(f_rec_list_str.empty()) {
				res_msg = "{\"response_type\":\"get flight record list\",\"list_len\":0,\"list\":[]}";
			} else {
				boost::format f_rec_list_fmt("{\"response_type\":\"get flight record list\",\"list_len\":%d,\"list\":[%s]}");
				f_rec_list_fmt % f_rec_list_count % f_rec_list_str;
				res_msg = f_rec_list_fmt.str();
			}
			Send(res_msg.c_str(),res_msg.size() + 1);
		} else if((std::string)f_type == "add flight record") {
			//進程表上報模塊實現
			//{"request_type":"get flight record list","record":"相關的數據結構"}
			//取出數據結構，然後存放到一個公共的位置
			//這裏展示將進程表的結構返回的時候構造成一個列表這樣好進行
			//返回
			Object f_rec_o = v["record"];
			//這裏構建基本列表
			if(!f_rec_list_str.empty()) {
				f_rec_list_str += ",";
			}
			f_rec_list_str += (std::string)f_rec_o;
			++f_rec_list_count;
			//進行響應
			//{"response_type":"get flight record list":"status":"<successful|failure>"}
			res_msg = "{\"response_type\":\"get flight record list\":\"status\":\"successful\"}";
			Send(res_msg.c_str(),res_msg.size() + 1);
		} else {
			//未知的消息，返回失敗的信息
			SendErr(CLIENT_REQ_TYPE_UNKNOWN,CLIENT_REQ_TYPE_UNKNOWN_DESC);
		}
	}
	void
	FlightChessBoardSession::Send(const char *buf,size_t len)
	{
		sfp_(buf,len);
	}
	void
	FlightChessBoardSession::SendErr(uint32_t err_no,const char *err_msg_str)
	{
		sefp_(err_no,err_msg_str);
	}
};
